home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / aijournl / 1989_05 / frames.cde < prev    next >
Text File  |  1988-05-03  |  9KB  |  236 lines

  1.  
  2.                Frame Unification
  3.  
  4.  
  5. /* frame_unify(Frame1, Frame2, Unification )
  6.    unifies two frames.  Slots that are present in one frame and not in
  7.    another are added to the unification, as if the slot had appeared in
  8.    the frame where it was absent with a variable value.
  9. */
  10.  
  11.                     /*  frame_unify                    */
  12. frame_unify(Frame1, Frame2, Unification ):-
  13.              % use frame_merge to implement frame_unify
  14.     frame_merge(Frame1, Frame2, Unification, slot_unify).
  15.  
  16.  
  17.  
  18.    %  slot_unify([Tag : Slot_val1, Slot_list2, Result, Fail_Flag ])
  19.    %
  20.    % unifies a slot with Tag with a member of a Slot_list2 if possible.
  21.  
  22.       % This first rule applies when Slot_list2 contains a slot with Tag.
  23.       % Result is the unification if it exists.
  24.       % Fail_Flag is set to fail if unification fails, to signal
  25.       % frame_merge to fail.
  26. slot_unify([Tag : Slot_val1, Slot_list2, Result, Fail_Flag ]):-
  27.               % get value for Tag
  28.     slot_list_val(Tag, Slot_list2, Slot_val2),
  29.               % If slot list 2 contains a slot with Tag,
  30.               % stay in this rule
  31.     !,
  32.               % if these slot values unify
  33.     (    value_unify(Slot_val1, Slot_val2, Result),
  34.               % then stay in this alternative
  35.          !,
  36.               % and tell frame_merge not to fail
  37.          Fail_Flag = true
  38.               % if the slot values do not unify
  39.               % tell frame_merge to fail
  40.       ;  Fail_Flag = false).
  41.  
  42.        % When the slot in arg. 1 does not appear in the
  43.        % arg. 2 slot list, the result of unify is the slot
  44.        % value in arg. 1
  45. slot_unify([ _  : Slot_val1, _ , Slot_val1 , _]):-  !.
  46.  
  47.  
  48. /*-------------------- value_unify -----------------------------------------*/
  49.  
  50.       % value_unify unifies slot values
  51.       % Arg 3 is the unification
  52.             % this rule unifies those things that are not frames
  53. value_unify(Slot_val1, Slot_val2,  Slot_val1):-
  54.              Slot_val1 = Slot_val2, !.
  55. è            % this rule unifies  frames
  56. value_unify(Slot_val1, Slot_val2, Result ):-
  57.     frame_merge(Slot_val1, Slot_val2, Result, slot_unify),
  58.     !.
  59.  
  60.            % set unify slot values that are sets
  61. value_unify(Slot_val1, Slot_val2, Slot_val1) :-
  62.     set_unify(  Slot_val1, Slot_val2  ) ,!.
  63.  
  64.  
  65. Intersecting Frames
  66.  
  67.  
  68. /* frame_intersect creates a new frame from 2 existing frames by
  69.     * keeping in slots that appear in both frames with values that unify,
  70.       and letting the value of such slots be the unification of the input
  71.       slot values
  72.     * deleting all other slots, including those where the same tag has
  73.       values in the two frames that don't unify.
  74. */
  75.  
  76. frame_intersect(Frame1, Frame2, Intersection ):-
  77.            % do this with frame_merge
  78.     frame_merge(Frame1, Frame2, Intersection, slot_intersect).
  79.  
  80. slot_intersect([Tag : Slot_val1, Slot_list2, New_slot_val, true    ]):-
  81.     slot_list_val(Tag, Slot_list2, Slot_val2), !,
  82.            % merge slot values
  83.     slot_merge0(Slot_val1, Slot_val2, New_slot_val, _  ).
  84.  
  85.            % note that when a slot with Tag is not in Slot_list2,
  86.            % slot_intersect fails.  This causes frame_merge to
  87.            % leave the Tag slot out of the computed Intersection
  88.  
  89.            % unify slots if possible
  90. slot_merge0(Slot_val1, Slot_val2, Slot_val1, _):-
  91.              Slot_val1 = Slot_val2, !.
  92.  
  93.            % intersect slot values that are frames
  94. slot_merge0(Slot_val1, Slot_val2, New_slot_val, _):-
  95.     frame_merge(Slot_val1, Slot_val2, New_slot_val, slot_intersect),
  96.     !.
  97.  
  98.            % set unify slot values that are sets
  99. slot_merge0(Slot_val1, Slot_val2, Slot_val1   , _):-
  100.     set_unify(  Slot_val1, Slot_val2  ) ,!.
  101.  
  102.  
  103. A General Frame Merging Predicate
  104.  
  105.  
  106. /*  frame_merge(Frame1,
  107.                 Frame2,
  108.                 New_frame,
  109.                 Slot_merge_pred,è                Slot_append_pred),
  110.  
  111.      merges Frame1 and Frame2 into New_frame, where Slot_merge_pred
  112.      is used to create the output slot.
  113.  
  114.  
  115. */
  116.  
  117.  
  118. frame_merge(Frame1, Frame2, New_frame, Slot_merge_pred):-
  119.                                          /*  2 frames must have same name:  */
  120.     frame_info(Frame1, Class_name, Slot_list1),
  121.     frame_info(Frame2, Class_name, Slot_list2),
  122.                                          /*  Merge the tag/slot lists:      */
  123.     slot_list_merge(Slot_list1, Slot_list2, New_slot_list, Slot_merge_pred),
  124.                                          /*  Construct the new frame:       */
  125.     New_frame =.. [Class_name, New_slot_list],
  126.     !.
  127.  
  128.  
  129. /*-------------------- slot_list_merge -------------------------------------*/
  130.  
  131. /* slot_list_merge( Slot_list1,
  132.                     Slot_list2,
  133.                     New_slot_list,
  134.                     Slot_merge_pred  )
  135.  
  136.    merges a pair of slot lists, where Slot_merge_pred is used to
  137.    merge the individual slots.
  138.  
  139.  
  140.  
  141. */
  142.  
  143.      %  Terminate the recursion when both input lists are empty
  144. slot_list_merge( [],
  145.                  [],
  146.                  [],
  147.                  _  )  :- !.
  148.  
  149.      % If both frames contain a slot with Tag, then use Slot_merge_pred
  150.      % to unify them.  Make slot_list_merge fail if Slot_merge_pred
  151.      % sets FailFlag to fail.  This lets us distinguish between
  152.      % two slot values failing to merge but wanting to go on, and
  153.      % wanting to quit when merge fails on the slot values.
  154.      %
  155.      % In particular, Slot_merge_pred's behavior is related to what
  156.      % slot_list_merge should do in the following way:
  157.      %
  158.      %  What slot_list_merge does    What Slot_merge_pred does
  159.      %  when slot values fail to     when slot values fail to
  160.      %  merge                        merge
  161.      %
  162.      %  fail                         set  FailFlag to fail and succeed
  163.      %è     %  leave out the slot           fail
  164.      %
  165.  
  166. slot_list_merge( [Tag : Slot_val1 | Slot_list1],
  167.                  Slot_list2,
  168.                  [Tag : New_slot_val | New_slot_list],
  169.                  Slot_merge_pred):-
  170.                     % create a term which will try to merge the
  171.                     % slot with Tag in the slot list in arg. 1, with
  172.                     % some frame in the slot list in arg. 2
  173.     make_call_term(Slot_merge_pred,
  174.                    [Tag : Slot_val1, Slot_list2, New_slot_val, FailFlag],
  175.                    Term),
  176.     call(Term),     % call that term
  177.     !,
  178.                     % cut, fail if FailFlag == fail
  179.     FailFlag \== fail,
  180.                     % remove the slot that merges from the 2nd. slot list
  181.     remove_if_slot(Tag, Slot_list2, New_slot_list2),
  182.                     % recurse
  183.     slot_list_merge(Slot_list1,
  184.                     New_slot_list2,
  185.                     New_slot_list,
  186.                     Slot_merge_pred).
  187.  
  188.      % Skip Tag:Slot_val1 if Slot_merge_pred failed.
  189. slot_list_merge([_ | Slot_list1],
  190.                Slot_list2,
  191.                New_slot_list,
  192.                Slot_merge_pred):-
  193.     slot_list_merge(Slot_list1,
  194.                     Slot_list2,
  195.                     New_slot_list,
  196.                     Slot_merge_pred).
  197.  
  198.      % When the first slot list is exhausted, switch the slot list
  199.      % arguments, and recurse.
  200. slot_list_merge([],
  201.                 [Slot | Slot_list],
  202.                 New_slot_list,
  203.                 Slot_merge_pred):-
  204.     slot_list_merge([Slot | Slot_list],
  205.                     [],
  206.                     New_slot_list,
  207.                     Slot_merge_pred).
  208.  
  209.  
  210. Using Frame Unify
  211.  
  212.  
  213.  
  214. f(part(X)):- part(X).        /*  Include part frames in test    */
  215.  
  216. test_merge:-
  217.       New_pin_frame = part([part_number : lm309,è                          class : ic,
  218.                              /*  Append info. to 'type' slot    */
  219.                              /*  for pins 3 and 4:              */
  220.                           pin(3): pin([type : set([high_gain])]),
  221.                           pin(4): pin([type : set([high_gain])]),
  222.                              /*  Add new pin descr. for pin 8:  */
  223.                           pin(8): pin([device_number : 2,
  224.                                        type : set([output]),
  225.                                        milliamps : [0, 100],
  226.                                        volts : [-7, 7]
  227.                                       ])
  228.                          ]),
  229.       !,
  230.       f(Frame),
  231.       frame_unify( Frame,
  232.                    New_pin_frame,
  233.                    New_frame),
  234.       frame_display(New_frame).
  235.  
  236.